#ifndef _PROJECT3_CARDINALBSPLINE_H_
#define _PROJECT3_CARDINALBSPLINE_H_

#include "Config.H"

template <int Order>
constexpr Real CardBSpline(int i, Real t);

template <>
constexpr Real CardBSpline<0>(int i, Real t)
{
    return (t <= i && t > i - 1) ? 1.0 : 0.0;
};

template <>
constexpr Real CardBSpline<1>(int i, Real t)
{
    if (t <= i - 1)
        return 0.0;
    else if (t <= i)
        return t - i + 1.0;
    else
        return CardBSpline<1>(i, 2 * i + 1 - 1 - t);
};

template <>
constexpr Real CardBSpline<2>(int i, Real t)
{
    if (t <= i - 1)
        return 0.0;
    else if (t <= i)
        return (t - i + 1.0) * (t - i + 1.0) / 2.0;
    else if (t <= i + 1)
        return 0.75 - (t - (i + 0.5)) * (t - (i + 0.5));
    else
        return CardBSpline<2>(i, 2 * i + 2 - 1 - t);
};

template <>
constexpr Real CardBSpline<3>(int i, Real t)
{
    if (t <= i - 1)
        return 0.0;
    else if (t <= i)
        return (t - i + 1.0) * (t - i + 1.0) * (t - i + 1.0) / 6.0;
    else if (t <= i + 1)
        return 2.0 / 3.0 - 0.5 * (t - i - 1.0) * (t - i - 1.0) * (t - i + 1.0);
    else
        return CardBSpline<3>(i, 2 * i + 3 - 1 - t);
};

#else
//do nothing
#endif
